package com.acmen.easyapi.generator;

import com.acmen.easyapi.annotation.Param;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.regex.Pattern;

/**
 * 数字获取器
 *
 * @author acmen
 * @date 2022-04-06
 */
@Component
public class NumberDataGenerator implements DataGenerator {
    private final static String PATTERN = "^num\\((([1-9][0-9]*)+(\\.[0-9]{1,3})?),(([1-9][0-9]*)+(\\.[0-9]{1,3})?)\\)";

    @Override
    public boolean matches(Field field, Param param) {
        boolean isMatch = Pattern.matches(PATTERN, param.testData()) || Pattern.matches(PATTERN, param.validateExp());
        // 判断是否匹配PATTERN模式，要么匹配param.testData()要么匹配param.validateExp()
        return isMatch;
        // 返回是否匹配的结果

    }

    @Override
    public Object generate(Field field, Param param) {
        // 根据给定的正则表达式判断参数是否匹配，如果匹配则返回参数值，否则返回参数的校验表达式
        String exp = Pattern.matches(PATTERN, param.testData()) ? param.testData() : param.validateExp();
        exp = exp.trim();
        exp = exp.substring("num(".length());
        exp = exp.substring(0, exp.length() - 1);

        // 将参数表达式按逗号分隔为字符串数组
        String[] nums = exp.split(",");

        // 将字符串数组转换为双精度浮点数数组，获取最小值和最大值
        Double min = Double.parseDouble(nums[0]);
        Double max = Double.parseDouble(nums[1]);

        // 创建随机数生成器对象
        Random random = new Random();

        // 如果字段类型是数组或者可分配给集合类，则生成一个数据列表
        if (field.getType().isArray() || Collection.class.isAssignableFrom(field.getType())) {
            List datas = new ArrayList();

            // 生成三个数据并添加到数据列表中
            for (int i = 0; i < 3; i++) {
                // 计算最大值和最小值之间的长度
                Double len = max - min;
                // 生成一个在长度范围内加上最小值的随机数
                Double d = random.nextInt(len.intValue()) + min;
                datas.add(d);
            }
            return datas;
        } else {
            // 如果字段类型不是数组或者不可分配给集合类，则生成一个数据

            // 计算最大值和最小值之间的长度
            Double len = max - min;
            // 生成一个在长度范围内加上最小值的随机数，并将其转换为整数
            Double d = random.nextInt(len.intValue()) + min;
            return d.intValue();
        }
    }


    /**
     * 数据获取说明
     *
     * @return
     */
    @Override
    public String getNote() {
        String note = "数字：";
        note += "匹配@ReqParam.testData或者@ReqParam.validateExp为'num(min,max)'；<br>";
        note += TAB + "①当字段为单一对象时随机生成一个大于或等于min且小于等于max的数字数组；<br>";
        note += TAB + "②当字段为数组或者列表时随机生成一个大于或等于min且小于等于max的数字数组。";
        return note;
    }
}
